package com.hys.app.mq.core.erp;

import com.hys.app.mq.event.*;
import com.hys.app.framework.util.DateUtil;
import com.hys.app.model.erp.dos.*;
import com.hys.app.model.erp.dto.StockStatisticsMessage;
import com.hys.app.model.erp.dto.message.*;
import com.hys.app.model.erp.enums.StockStatisticsTypeEnum;
import com.hys.app.service.erp.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 库存统计消费者
 *
 * @author dmy
 * 2023-12-22
 */
@Service
public class StockStatisticsConsumer implements StockStatisticsEvent, WarehouseEntryAuditPassEvent, SupplierReturnAuditPassEvent, WarehouseOutShipEvent, StockDamageAuditPassEvent, OrderReturnAuditPassEvent, ChangeFormAuditPassEvent, GoodsChangeEvent {

    @Autowired
    private StockStatisticsManager stockStatisticsManager;

    @Autowired
    private WarehouseEntryBatchManager warehouseEntryBatchManager;

    @Autowired
    private ProductManager productManager;

    @Autowired
    private ProductStockManager productStockManager;

    @Autowired
    private SupplierReturnItemManager supplierReturnItemManager;

    @Autowired
    private OrderReturnItemManager orderReturnItemManager;

    @Autowired
    private StockTransferProductManager stockTransferProductManager;

    @Autowired
    private StockDamageReportProductManager stockDamageReportProductManager;

    @Autowired
    private ChangeFormProductManager changeFormProductManager;

    /**
     * 库存统计
     *
     * @param message 库存统计消息
     */
    @Override
    public void stockStatistics(StockStatisticsMessage message) {
        //获取操作类型
        StockStatisticsTypeEnum typeEnum = message.getStockStatisticsTypeEnum();
        if (StockStatisticsTypeEnum.STOCK_TRANSFER.equals(typeEnum)) {
            //更新库存统计中的库存调拨数量信息
            this.updateStockTransferNum(message.getStockTransferList());
        }
    }

    @Override
    public void onWarehouseEntryAuditPass(WarehouseEntryAuditPassMessage message) {
        // 新增库存统计信息
        add(message.getList());
    }

    @Override
    public void onSupplierReturnAuditPass(SupplierReturnAuditPassMessage message) {
        //更新库存统计中的供应商退货数量信息
        this.updateSupplierReturnNum(message.getList());
    }

    @Override
    public void onWarehouseOutShip(WarehouseOutShipMessage message) {
        //更新库存统计中的出库数量信息
        this.updateStockOutNum(message.getItemList());
    }

    @Override
    public void onStockDamageAuditPass(StockDamageAuditPassMessage message) {
        //更新库存统计中的库存报损数量信息
        this.updateStockDamageNum(message.getList());
    }

    @Override
    public void onOrderReturnAuditPass(OrderReturnAuditPassMessage message) {
        //更新库存统计中的订单退货数量信息
        this.updateOrderReturnNum(message.getList());
    }

    @Override
    public void onChangeFormAuditPass(ChangeFormAuditPassMessage message) {
        //更新库存统计中的换货数量信息
        this.updateChangeNum(message.getList());
    }

    /**
     * 新增库存统计信息
     *
     * @param warehouseEntryList 入库单信息
     */
    private void add(List<WarehouseEntryDO> warehouseEntryList) {
        //库存统计信息入库
        for (WarehouseEntryDO warehouseEntryDO : warehouseEntryList) {
            StockStatistics statistics = new StockStatistics();
            statistics.setWarehouseId(warehouseEntryDO.getWarehouseId());
            statistics.setWarehouseName(warehouseEntryDO.getWarehouseName());
            statistics.setDeptId(warehouseEntryDO.getDeptId());
            statistics.setDeptName(warehouseEntryDO.getDeptName());
            statistics.setStockSn(warehouseEntryDO.getSn());
            statistics.setCreateTime(DateUtil.getDateline());

            //根据入库单ID查询入库批次信息
            List<WarehouseEntryBatchDO> batchDOS = this.warehouseEntryBatchManager.listByWarehouseEntryIds(Collections.singletonList(warehouseEntryDO.getId()));

            List<StockStatistics> stockStatisticsList = new ArrayList<>();
            for (WarehouseEntryBatchDO batch : batchDOS) {
                statistics.setBatchId(batch.getId());
                statistics.setBatchSn(batch.getSn());
                statistics.setProductId(batch.getProductId());
                statistics.setProductSn(batch.getProductSn());
                statistics.setProductName(batch.getProductName());
                statistics.setSpecification(batch.getProductSpecification());
                statistics.setCategoryId(batch.getCategoryId());
                statistics.setCategoryName(batch.getCategoryName());
                statistics.setUnit(batch.getProductUnit());
                statistics.setInNum(batch.getEntryNum());
                statistics.setRemainNum(batch.getRemainNum());
                statistics.setOutNum(0);
                statistics.setSupplierReturnNum(0);
                statistics.setOrderReturnNum(0);
                statistics.setTransferOutNum(0);
                statistics.setTransferInNum(0);
                statistics.setDamageNum(0);
                statistics.setChangeNum(0);
                //设置商品预警数量
                ProductDO product = this.productManager.getById(batch.getProductId());
                statistics.setWarningNum(product.getWarningValue());
                //设置商品总库存
                ProductStockDO stock = this.productStockManager.getStock(batch.getProductId(), batch.getWarehouseId());
                statistics.setStockNum(stock.getNum());
                //放入集合中
                stockStatisticsList.add(statistics);
            }
            this.stockStatisticsManager.saveBatch(stockStatisticsList);
        }
    }

    /**
     * 更新库存统计中的出库数量
     *
     * @param warehouseOutItemList 出库单商品信息集合
     */
    private void updateStockOutNum(List<WarehouseOutItemDO> warehouseOutItemList) {
        //库存统计信息集合
        List<StockStatistics> statisticsList = new ArrayList<>();
        //更新库存统计中的出库数量
        for (WarehouseOutItemDO warehouseOutItemDO : warehouseOutItemList) {
            //获取库存统计信息
            StockStatistics statistics = this.stockStatisticsManager.getModel(warehouseOutItemDO.getWarehouseEntryBatchId());
            //设置库存统计中的出库数量
            statistics.setOutNum(statistics.getOutNum() + warehouseOutItemDO.getOutNum());
            //设置库存剩余数量
            statistics.setRemainNum(statistics.getRemainNum() - warehouseOutItemDO.getOutNum());
            //设置商品总库存
            ProductStockDO stock = this.productStockManager.getStock(statistics.getProductId(), statistics.getWarehouseId());
            statistics.setStockNum(stock.getNum());
            //放入集合中
            statisticsList.add(statistics);
        }
        //批量修改
        this.stockStatisticsManager.updateBatchById(statisticsList);
    }

    /**
     * 更新库存统计中的供应商退货数量
     *
     * @param supplierReturnList 供应商退货信息
     */
    private void updateSupplierReturnNum(List<SupplierReturnDO> supplierReturnList) {
        //库存统计信息集合
        List<StockStatistics> statisticsList = new ArrayList<>();
        //循环修改
        for (SupplierReturnDO supplierReturnDO : supplierReturnList) {
            //获取供应商退货产品信息
            List<SupplierReturnItemDO> itemDOS = this.supplierReturnItemManager.listBySupplierReturnId(supplierReturnDO.getId());
            for (SupplierReturnItemDO itemDO : itemDOS) {
                //获取库存统计信息
                StockStatistics statistics = this.stockStatisticsManager.getModel(itemDO.getWarehouseEntryBatchId());
                //设置库存统计中的供应商退货数量
                statistics.setSupplierReturnNum(statistics.getSupplierReturnNum() + itemDO.getReturnNum());
                //设置库存剩余数量
                statistics.setRemainNum(statistics.getRemainNum() - itemDO.getReturnNum());
                //设置商品总库存
                ProductStockDO stock = this.productStockManager.getStock(statistics.getProductId(), statistics.getWarehouseId());
                statistics.setStockNum(stock.getNum());
                //放入集合中
                statisticsList.add(statistics);
            }
        }
        //批量修改
        this.stockStatisticsManager.updateBatchById(statisticsList);
    }

    /**
     * 更新库存统计中的订单退货数量
     *
     * @param orderReturnList 订单退货信息
     */
    private void updateOrderReturnNum(List<OrderReturnDO> orderReturnList) {
        //库存统计信息集合
        List<StockStatistics> statisticsList = new ArrayList<>();
        //循环修改
        for (OrderReturnDO orderReturnDO : orderReturnList) {
            //获取订单退货产品信息
            List<OrderReturnItemDO> itemDOS = this.orderReturnItemManager.listByOrderReturnId(orderReturnDO.getId());
            for (OrderReturnItemDO itemDO : itemDOS) {
                //获取库存统计信息
                StockStatistics statistics = this.stockStatisticsManager.getModel(itemDO.getWarehouseEntryBatchId());
                //设置库存统计中的订单退货数量
                statistics.setOrderReturnNum(statistics.getOrderReturnNum() + itemDO.getReturnNum());
                //设置库存剩余数量
                statistics.setRemainNum(statistics.getRemainNum() + itemDO.getReturnNum());
                //设置商品总库存
                ProductStockDO stock = this.productStockManager.getStock(statistics.getProductId(), statistics.getWarehouseId());
                statistics.setStockNum(stock.getNum());
                //放入集合中
                statisticsList.add(statistics);
            }
        }
        //批量修改
        this.stockStatisticsManager.updateBatchById(statisticsList);
    }

    /**
     * 更新库存统计中的库存调拨数量
     *
     * @param stockTransferList 库存调拨信息
     */
    private void updateStockTransferNum(List<StockTransferDO> stockTransferList) {
        //库存统计信息集合
        List<StockStatistics> statisticsList = new ArrayList<>();
        //循环修改
        for (StockTransferDO stockTransferDO : stockTransferList) {
            //获取库存调拨单产品信息
            List<StockTransferProductDO> productDOS = this.stockTransferProductManager.listByStockTransferId(stockTransferDO.getId());
            for (StockTransferProductDO productDO : productDOS) {
                //获取库存统计信息
                StockStatistics statistics = this.stockStatisticsManager.getModel(productDO.getWarehouseEntryBatchId());
                statistics.setTransferOutNum(statistics.getTransferOutNum() + productDO.getNum());
                //设置库存剩余数量
                statistics.setRemainNum(statistics.getRemainNum() - productDO.getNum());

                //设置商品总库存
                ProductStockDO stock = this.productStockManager.getStock(statistics.getProductId(), statistics.getWarehouseId());
                statistics.setStockNum(stock.getNum());
                //放入集合中
                statisticsList.add(statistics);
            }
        }
        //批量修改
        this.stockStatisticsManager.updateBatchById(statisticsList);
    }

    /**
     * 更新库存统计中的库存调整数量
     *
     * @param reportsList 库存调整信息
     */
    private void updateStockDamageNum(List<StockDamageReport> reportsList) {
        //库存统计信息集合
        List<StockStatistics> statisticsList = new ArrayList<>();
        //循环修改
        for (StockDamageReport report : reportsList) {
            //获取库存报损单产品信息
            List<StockDamageReportProduct> productDOS = this.stockDamageReportProductManager.list(report.getId());
            for (StockDamageReportProduct productDO : productDOS) {
                //获取库存统计信息
                StockStatistics statistics = this.stockStatisticsManager.getModel(productDO.getBatchId());
                //修改库存调整数量
                statistics.setDamageNum(statistics.getDamageNum() - productDO.getReportNum());
                //设置库存剩余数量
                statistics.setRemainNum(statistics.getRemainNum() + productDO.getReportNum());
                //设置商品总库存
                ProductStockDO stock = this.productStockManager.getStock(statistics.getProductId(), statistics.getWarehouseId());
                statistics.setStockNum(stock.getNum());
                //放入集合中
                statisticsList.add(statistics);
            }
        }
        //批量修改
        this.stockStatisticsManager.updateBatchById(statisticsList);
    }

    /**
     * 更新库存统计中的库存换货数量
     *
     * @param formList 换货单信息
     */
    private void updateChangeNum(List<ChangeForm> formList) {
        //库存统计信息集合
        List<StockStatistics> statisticsList = new ArrayList<>();
        //循环修改
        for (ChangeForm form : formList) {
            //获取库存报损单产品信息
            List<ChangeFormProduct> productDOS = this.changeFormProductManager.list(form.getId(), null);
            for (ChangeFormProduct productDO : productDOS) {
                //获取库存统计信息
                StockStatistics statistics = this.stockStatisticsManager.getModel(productDO.getStockBatchId());
                //判断操作类型 0：退货，1：换货
                if (productDO.getType() == 0) {
                    //增加换货数量
                    statistics.setChangeNum(statistics.getChangeNum() + productDO.getNum());
                    //设置库存剩余数量
                    statistics.setRemainNum(statistics.getRemainNum() + productDO.getNum());
                } else {
                    //减少换货数量
                    statistics.setChangeNum(statistics.getChangeNum() - productDO.getNum());
                    //设置库存剩余数量
                    statistics.setRemainNum(statistics.getRemainNum() - productDO.getNum());
                }

                //设置商品总库存
                ProductStockDO stock = this.productStockManager.getStock(statistics.getProductId(), statistics.getWarehouseId());
                statistics.setStockNum(stock.getNum());
                //放入集合中
                statisticsList.add(statistics);
            }
        }
        //批量修改
        this.stockStatisticsManager.updateBatchById(statisticsList);
    }

    @Override
    public void onGoodsChange(GoodsChangeMessage message) {
        if (message.getGoodsChangeType() == GoodsChangeMessage.GoodsChangeType.Add || message.getGoodsChangeType() == GoodsChangeMessage.GoodsChangeType.Edit) {
            List<ProductDO> productList = productManager.listByGoodsId(message.getId());
            for (ProductDO productDO : productList) {
                //更新库存统计中的产品预警库存数量信息
                this.stockStatisticsManager.updateStockWarningNum(productDO.getId(), productDO.getWarningValue());
            }
        }
    }
}
